﻿'use strict';
/**
 * Created by FreezeSoul on 2015/10/23. 
 */
define([
    "app/core/base",
    "app/core/util",
    "../echartsMeta",
    "jquery",
    "underscore",
    'JSONParse',
    'loglevel',
    "echarts"
], function (Chart, Util, Meta, $, _, JSON, log, ec) {

    var property = {
        name: '通用属性',
        config: "property",
        option: []
            .concat($.extend(true, [], Meta.titleProperties))
            .concat($.extend(true, [], Meta.legendProperties))
            .concat($.extend(true, [], Meta.tooltipProperties))
            .concat($.extend(true, [], Meta.toolboxProperties))
            .concat([
                {
                    group: '序列',
                    id: 'f53a0a43-6d1b-43e0-b514-122a8b155ece0',
                    name: '序列',
                    type: 'group',
                    items: [],
                    option: [
                        {
                            id: '8d613598-8e08-49ce-908e-7524c305910f0',
                            name: '序列名称',
                            enable: true,
                            type: 'text',
                            value: '',
                            default: '',
                            link: 'name',
                            tooltip: '序列名称，用于legend'
                        },
                        {
                            id: '17994381-e1fe-4551-a852-a5a0571ed8991',
                            name: '序列绑定',
                            enable: true,
                            type: 'seriesBinding',
                            dataset: '',
                            dimension: '',
                            measure: '',
                            tooltip: '序列绑定设置，与数据集关系'
                        },
                        {
                            id: 'a320684c-8ca5-49f0-aab7-853e0fde9e5c',
                            name: '过滤列名称',
                            enable: false,
                            type: 'text',
                            value: '',
                            default: '',
                            tooltip: '绑定数据集，客户端过滤字段列名称'
                        },
                        {
                            id: '96f30ae6-6fe0-4faa-8b7f-a302a49a0434',
                            name: '过滤列默认值',
                            enable: false,
                            type: 'text',
                            value: '',
                            default: '',
                            tooltip: '绑定数据集，客户端过滤字段默认值'
                        },
                        {
                            id: 'funnel_gap',
                            name: '选项间距',
                            enable: false,
                            type: 'number',
                            value: '2',
                            link: 'gap',
                            tooltip: '展示项间距'
                        },
                        {
                            id: 'funnel_label_normal_position',
                            name: '标签显示位置',
                            enable: true,
                            type: 'select',
                            value: 'inside',
                            data: [
                                {value: 'inside', text: '内部'},
                                {value: 'outside', text: '外部'},
                                {value: 'center', text: '中心'}
                            ],
                            link: function (option) {
                                var _this = this;
                                if (_this.enable) {
                                    Util.setOption("label.normal.position", _this.value, option);
                                    if (_this.value == 'outside') {
                                        Util.setOption("labelLine.normal.show", true, option);
                                    } else {
                                        Util.setOption("labelLine.normal.show", false, option);
                                    }
                                }
                            },
                            tooltip: '序列标签显示位置设置'
                        },
                        {
                            id: 'funnel_label_emphasis_textStyle_fontSize',
                            name: '标签字体大小',
                            enable: false,
                            type: 'number',
                            value: 20,
                            link: 'label.emphasis.textStyle.fontSize',
                            tooltip: '序列标签鼠标放置显示大小设置'
                        },
                        {
                            id: 'funnel_itemStyle_normal_borderColor',
                            name: '选项边框颜色设置',
                            enable: false,
                            type: 'color',
                            value: 'transparent',
                            link: 'itemStyle.normal.borderColor',
                            tooltip: '序列选项边框颜色设置'
                        },
                        {
                            id: 'funnel_itemStyle_normal_borderWidth',
                            name: '选项边框宽度设置',
                            enable: false,
                            type: 'number',
                            value: 1,
                            link: 'itemStyle.normal.borderWidth',
                            tooltip: '序列选项边框宽度设置'
                        }
                    ],
                    link: 'series',
                    tooltip: '字段说明:<br/>分组控件，支持动态扩展，内部可增加支持的类型属性'
                }
            ]).concat($.extend(true, [], Meta.otherProperties)),
        //需要针对组件映射属性至组件Option
        MapOption: function (option) {
            Util.linkOption(this.option, option);

            //link支持function与linkString，下面演示如果没有link时自定义绑定的方法
            //当然，如果上面link已经指定了function，就无需下面的代码了
            /*
             var xAxisSplitLine = _.findWhere(this.option,{name:'X轴分割线'});
             var yAxisSplitLine = _.findWhere(this.option,{name:'Y轴分割线'});
             if (xAxisSplitLine && xAxisSplitLine.enable && $.isArray(option.xAxis)) {
             _.each(option.xAxis, function (xAxis) {
             Util.setOption("splitLine.show", xAxisSplitLine.value, xAxis);
             });
             }
             if (yAxisSplitLine && yAxisSplitLine.enable && $.isArray(option.yAxis)) {
             _.each(option.yAxis, function (yAxis) {
             Util.setOption("splitLine.show", yAxisSplitLine.value, yAxis);
             });
             }*/
        }
    };

    var funnel = Chart.extend({
        constructor: function (layout) {
            this._layout = layout;
            this._chart = null;
            this._lastdata = null;
            this._container = null;
            this._option = {
                Binding: [],
                Events: [],
                Extend: $.extend(true, {}, property),
                Option: {
                    title: {
                        text: '漏斗图',
                        subtext: '纯属虚构'
                    },
                    tooltip: {
                        trigger: 'item',
                        formatter: "{a} <br/>{b} : {c}%"
                    },
                    toolbox: {
                        feature: {
                            dataView: {readOnly: false},
                            restore: {},
                            saveAsImage: {}
                        }
                    },
                    legend: {
                        data: ['展现', '点击', '访问', '咨询', '订单']
                    },
                    calculable: true,
                    series: [
                        {
                            name: '漏斗图',
                            type: 'funnel',
                            left: '10%',
                            top: 60,
                            //x2: 80,
                            bottom: 60,
                            width: '80%',
                            // height: {totalHeight} - y - y2,
                            min: 0,
                            max: 100,
                            minSize: '0%',
                            maxSize: '100%',
                            sort: 'descending',
                            gap: 2,
                            label: {
                                normal: {
                                    show: true,
                                    position: 'inside'
                                },
                                emphasis: {
                                    textStyle: {
                                        fontSize: 20
                                    }
                                }
                            },
                            labelLine: {
                                normal: {
                                    length: 10,
                                    lineStyle: {
                                        width: 1,
                                        type: 'solid'
                                    }
                                }
                            },
                            itemStyle: {
                                normal: {
                                    borderColor: '#fff',
                                    borderWidth: 1
                                }
                            },
                            data: [
                                {value: 60, name: '访问'},
                                {value: 40, name: '咨询'},
                                {value: 20, name: '订单'},
                                {value: 80, name: '点击'},
                                {value: 100, name: '展现'}
                            ]
                        }
                    ]
                }
            };
        },
        init: function (element) {
            try {
                this._container = element;
                this._chart = ec.init(element, null, {
                    renderer: 'canvas'
                });
                this._bindEvent();
            } catch (e) {
                log.error(e);
            }
        },
        //TODO:需要重写的部分
        _bindEvent: function () {
            var _this = this;
            this._chart.on("click", function (param) {
                if (_this._layout
                    && _this._layout.navigate
                    && _this._option.Events
                    && _this._option.Events.length > 0) {

                    var registerEvent = _.findWhere(_this._option.Events, {Event: "SeriesClick"});
                    if (registerEvent) {
                        var pageId = registerEvent.PageId;
                        var params = registerEvent.Params;
                        var args = [];
                        var dParam = _.findWhere(params, {Value: "Dimension"});
                        if (dParam && dParam.ParamName) {
                            args.push({
                                ParamName: dParam.ParamName,
                                ParamValue: param.name
                            });
                        }
                        var mParam = _.findWhere(params, {Value: "Measure"});
                        if (mParam && mParam.ParamName) {
                            args.push({
                                ParamName: mParam.ParamName,
                                ParamValue: param.value
                            });
                        }
                        var sParam = _.findWhere(params, {Value: "SeriesName"});
                        if (sParam && sParam.ParamName) {
                            args.push({
                                ParamName: sParam.ParamName,
                                ParamValue: param.seriesName
                            });
                        }
                        _this._layout.navigate(pageId, args);

                    }
                    param.event.event.preventDefault();
                }
            });
            if (!this._filterDataHandle) {
                this._filterDataHandle = function (params) {
                    _this.filterDataHandle.call(_this, params);
                };
            }
            this._layout.removeListener("filterData", this._filterDataHandle);
            this._layout.addListener("filterData", this._filterDataHandle);
        },
        filterDataHandle: function (params) {
            var _this = this;
            var flag = false;
            var seriesItems = _.findWhere(_this._option.Extend.option, {type: 'group'});
            $.each(seriesItems.items, function (i, item) {
                var filterColumn = _.findWhere(item.option, {name: '过滤列名称'});
                var filterValue = _.findWhere(item.option, {name: '过滤列默认值'});

                if (filterColumn && filterValue
                    && filterColumn.enable && filterValue.enable
                    && filterColumn.value !== "" && filterValue.value !== ""
                ) {
                    for (var prop in params) {
                        if (!params.hasOwnProperty(prop)) continue;
                        if (filterColumn.value === prop) {
                            filterValue.value = params[prop];
                            flag = true;
                        }
                    }
                }
            });
            if (flag && _this._lastdata) {
                _this.setData(_this._lastdata);
            }
        },
        example: function () {
            try {
                this._chart.setOption(this._option.Option, true);
            } catch (e) {
                log.error(e);
            }
        },
        _readProperty: function () {
            try {
                if (!this._option.Extend) return;
                Util.deepMapOption(property, this._option.Extend, this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        //TODO:需要重写的部分
        _bindData: function (data) {
            var tables = data;
            var _this = this;


            //根据每个option自行查找，可通过id或name，这里因为只有一个group,因此通过type查找
            var seriesItems = _.findWhere(this._option.Extend.option, {type: 'group'});

            //清除工作
            if (seriesItems.items.length > 0) {
                this._option.Option.legend.data = [];
            }

            //绑定数据
            $.each(seriesItems.items, function (i, item) {
                var bindProperty = _.findWhere(item.option, {type: 'seriesBinding'});
                if (!bindProperty) return;

                var dataSetCode = bindProperty.dataset;
                var dimensionCode = bindProperty.dimension.ColumnCode;
                var measureCode = bindProperty.measure.ColumnCode;

                var nameProperty = _.findWhere(item.option, {name: '序列名称'});


                if (dataSetCode && dimensionCode && measureCode) {
                    var table = tables[dataSetCode];

                    var binding = _.findWhere(_this._option.Binding, {DataSetCode: dataSetCode});
                    var dimension = _.findWhere(binding.Dimensions, {Code: dimensionCode}).Column;
                    var measure = _.findWhere(binding.Measures, {Code: measureCode}).Column;
                    var data = [];

                    table = _this._filterTable(item.option, table);
                    $.each(table, function (j, row) {
                        if (_this._option.Option.legend.data.indexOf(row[dimension]) === -1) {
                            _this._option.Option.legend.data.push(row[dimension]);
                        }
                        data.push({
                            value: row[measure],
                            name: row[dimension]
                        });
                    });
                    if (_this._option.Option.series.length >= i + 1) {
                        _this._option.Option.series[i].data = data;
                    }
                }
            });
        },
        _filterTable: function (option, table) {
            var filterColumn = _.findWhere(option, {name: '过滤列名称'});
            var filterValue = _.findWhere(option, {name: '过滤列默认值'});

            if (filterColumn && filterValue
                && filterColumn.enable && filterValue.enable
                && filterColumn.value !== "" && filterValue.value !== ""
            ) {
                var tableCopy = _.map(table, _.clone);
                return _.filter(tableCopy, function (row) {
                    return row[filterColumn.value] === filterValue.value;
                });
            }
            return table;
        },
        setData: function (data) {
            try {
                this._lastdata = data;

                this._readProperty();

                if (data
                    && this._option.Binding
                    && this._option.Binding.length > 0
                    && this._option.Extend) {

                    this._bindData(data);

                    this._readProperty();
                }
                this._chart.setOption(this._option.Option, true);

                //Util.setEChartsMeta(this, this._container, this._option.Extend.option);
            } catch (e) {
                log.error(e);
            }
        },
        setOption: function (option) {
            try {
                return this._option = $.extend(true, {}, option);
            } catch (e) {
                log.error(e);
            }
        },
        getOption: function () {
            try {
                this._readProperty();
            } catch (e) {
                log.error(e);
            }
            return this._option;
        },
        setTheme: function (theme) {
            try {
                this._chart.setTheme(theme);
            } catch (e) {
                log.error(e);
            }
        },
        resize: function () {
            try {
                this._chart.resize();
            } catch (e) {
                log.error(e);
            }
        },
        showLoading: function () {
            try {
                if (this._layout && this._layout.showLoading) {
                    this._layout.showLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        hideLoading: function () {
            try {
                if (this._layout && this._layout.hideLoading) {
                    this._layout.hideLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        dispose: function () {
            try {
                this._chart.dispose();
                this._layout.removeListener("filterData", this._filterDataHandle);
            } catch (e) {
                log.error(e);
            }
        },
        getElement: function () {
            return this._container;
        },
        getChart: function () {
            return this._chart;
        }
    });

    return {
        Chart: funnel,
        Property: property
    };
});

